Матч
409, Сеть из телепортов (TeleportsNetwork)
Дивизион 2,
Уровень 3
Королевство
Байтляндия состоит из множества городов, центром которого является столица. Для
связи со столицей король решил проложить дороги между городами. Каждый город,
кроме столицы, должен построить одну дорогу, ведущую в другой город. Город, в
который будет проведена дорога из Х, выбирается по следующему алгоритму:
1. Вычисляем Евклидово расстояние
от каждого города Байтляндии до столицы. Выбираем к дальнейшему рассмотрению
только те города, расстояния от которых до столицы в точности меньше расстояния
от Х до столицы. В выбранное множество
городов также включаем столицу;
2. Если выбранное множество
содержит более одного города, то то выбираем тот, который ближе всего находится
к Х;
3. Если городов, выбранных в
пункте 2, несколько, то берем тот, который имеет меньшую x координату;
4. Если городов, выбранных в
пункте 3, несколько, то берем тот, который имеет меньшую y координату;
После построения дорого люди
стали жаловаться на то, что из некоторых городов стало долго добираться до
столицы. Король решил решить эту проблему при помощи постройки teleportCount телепортов. Телепорт можно
построить в любом городе, и он мгновенно доставит жителя этого города в
столицу.
Неудобством города назовем
количество дорог, которое следует пройти его жителю для попадания в столицу.
Неудобство столицы и всех городов, в которых содержится телепорт, равно 0.
Неудобство города, в котором нет телепорта, но напрямую связанного дорогой со
столицей или городом с телепортом, равно 1. Неудобство королевства равно
суммарному неудобству городов.
Координаты i - го города заданы в ячейках (citiesX[i], citiesY[i]). Нулевой
город является столицей. Распределить teleportCount
телепортов между городами так, чтобы неудобство королевства было
наименьшим. Вернуть это значение.
Класс: TeleportsNetwork
Метод: int
distribute(int teleportCount, vector<int> citiesX,
vector<int> citiesY)
Ограничения: citiesX и citiesY содержат одинаковое количество
элементов – от 1 до 50, 0 £
citiesX[i], citiesY[i] £
1000000, 0 £ teleportCount £ 4.
Вход. Количество телепортов teleportCount
и массивы citiesX, citiesY, описывающие координаты городов.
Выход. Величина наименьшего неудобства королевства.
Пример входа
teleportCount |
citiesX |
citiesY |
2 |
{0,1,1,1,2,2} |
{1,0,1,2,0,2} |
1 |
{0,1,1,1,2,2} |
{1,0,1,2,0,2} |
0 |
{0,1,1,1,2,3,3,4} |
{1,1,2,0,0,0,2,1} |
Пример выхода
1
2
5
РЕШЕНИЕ
Флойд-Уоршел + перебор
Построим граф, описанный в
условии задачи, в функции BuildGraph. Функция FindCity находит город, к
которому будет проведена дорога из city.
Массив c в функции FindCity содержит множество городов, расстояние до которых
меньше расстояния от city до столицы.
Функция FindDistances вычисляет
расстояния между всеми парами городов при помощи алгоритма Флойда-Уоршела. Вес каждой дороги равен 1.
Генерируем все возможные
расстановки телепортов в городах (их не более 4) в функции GenCombinations. Для
каждой расстановки телепортов вычисляем неудобство королевства при помощи
функции KingdomInconv. Среди всех расстановок находим ту, для которой
неудобство королевства наименьшее.
ПРОГРАММА
#include <cstdio>
#include <vector>
#include <memory>
#define MAX 2000000000
using namespace std;
int g[51][51],d[51][51];
int n,Result = MAX;
long long dist(long long x1, long long y1, long long x2, long long y2)
{
return (x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2);
}
int FindCity(int city,
vector<int> &citiesX, vector<int> &citiesY)
{
vector<int> c;
long long
temp,BestDist,MyDist =
dist(citiesX[city],citiesY[city],citiesX[0],citiesY[0]);
int i, iBest;
for(i = 0; i < citiesX.size(); i++)
{
temp = dist(citiesX[i],citiesY[i],citiesX[0],citiesY[0]);
if (temp < MyDist) c.push_back(i);
}
BestDist = (long long)MAX * MAX; iBest=-1;
for(i = 0; i < c.size(); i++)
{
temp = dist(citiesX[city],citiesY[city],citiesX[c[i]],citiesY[c[i]]);
if (temp < BestDist)
{
BestDist = temp; iBest = c[i];
}
else if
(temp == BestDist)
if (citiesX[c[i]] < citiesX[iBest] ||
(citiesX[c[i]] == citiesX[iBest] &&
citiesY[c[i]] < citiesY[iBest]))iBest = c[i];
}
return iBest;
}
void BuildGraph(vector<int>
&citiesX, vector<int> &citiesY)
{
int i, j, n = citiesX.size();
memset(g,0,sizeof(g));
for(i = 1; i < n; i++)
{
j = FindCity(i,citiesX,citiesY);
g[i][j] = g[j][i] = 1;
}
}
void FindDistances(void)
{
int i, j, k;
memset(d,0x3F,sizeof(d));
for(i = 0; i < n; i++)
{
d[i][i] = 0;
for(j = 0; j < n; j++)
if (g[i][j]) d[i][j] = 1;
}
for(k = 0; k < n; k++)
for(i = 0; i < n; i++)
for(j = 0; j < n; j++)
d[i][j] = min(d[i][j],d[i][k]+d[k][j]);
}
int Inconv(int v,vector<int> &Teleports)
{
int res = d[v][0], i;
for(i = 0; i < Teleports.size(); i++)
res = min(res,d[v][Teleports[i]]);
return res;
}
int KingdomInconv(vector<int>
&Teleports)
{
int i,MaxInconv = 0;
for(i = 0; i < n; i++)
MaxInconv = max(MaxInconv,Inconv(i,Teleports));
return MaxInconv;
}
void GenCombinations(int index,int minValue,vector<int>
&Teleports)
{
int i;
if (index == Teleports.size())
Result = min(Result,KingdomInconv(Teleports));
else
for(i = minValue; i < n; i++)
{
Teleports[index] = i;
GenCombinations(index+1,i+1,Teleports);
}
}
class TeleportsNetwork
{
public:
int distribute(int
teleportCount, vector<int> citiesX,
vector<int> citiesY)
{
vector<int> m(teleportCount,0);
n = citiesX.size();
BuildGraph(citiesX,citiesY);
FindDistances();
GenCombinations(0,1,m);
return Result;
}
};